package org.tema.web;

import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;
import javax.persistence.NoResultException;

import org.tema.ejb.ProductBeanLocal;
import org.tema.ejb.TestCaseBeanLocal;
import org.tema.ejb.TestPlanBeanLocal;
import org.tema.entities.Product;
import org.tema.entities.TestCase;
import org.tema.entities.TestPlan;
import org.tema.entities.User;

public class ManageTestPlansBean {
	
	// navigation constants
	private static final String PLANS_LIST = "plansList";
	private static final String EDIT_PLAN = "editPlan";
	
	@EJB
	private TestPlanBeanLocal testPlanBean;
	@EJB
	private ProductBeanLocal productBean;
	@EJB 
	private TestCaseBeanLocal testCaseBean;
	
	private TestPlanSearchTypes searchDropDown;
	private String searchWord;
	private String searchWordProduct = null;
	private List <String> searchWordTestCase;
	private Collection <TestPlan> testPlanList = null;
	private int testPlanId;
	private TestPlan singleTestPlan;
	private User user;
	private Product product;
	private HtmlDataTable dataTable;
	private HtmlInputHidden dataItemId = new HtmlInputHidden();
	
	//individual variables for the test plan
	private String summary;
	private Date cDate;
	private Date mDate;
	private String testCycle;
	private float planedTime;
	private java.util.Date startDate;
	private java.util.Date endDate;
	
	public ManageTestPlansBean() {
		
	}
	
	
	////accessors start
	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	public HtmlInputHidden getDataItemId() {
		return dataItemId;
	}

	public void setDataItemId(HtmlInputHidden dataItemId) {
		this.dataItemId = dataItemId;
	}

	
	///real methods besides accessors
	
	
	public TestPlanSearchTypes getSearchDropDown() {
		return searchDropDown;
	}


	public void setSearchDropDown(TestPlanSearchTypes searchDropDown) {
		this.searchDropDown = searchDropDown;
	}


	public String getSearchWord() {
		return searchWord;
	}


	public String getSummary() {
		return summary;
	}

	public void setSummary(String summary) {
		this.summary = summary;
	}

	public Date getCDate() {
		return cDate;
	}

	public void setCDate(Date date) {
		date = new java.sql.Date(System.currentTimeMillis());
		cDate = date;
	}

	public Date getMDate() {
		return mDate;
	}

	public void setMDate(Date date) {
		//date = new java.sql.Date(System.currentTimeMillis());
		mDate = date;
	}

	public Collection<TestPlan> getTestPlanList() {
		if(testPlanList == null){
			findAll();
		}
		return testPlanList;
	}

	public void setTestPlanList(Collection<TestPlan> testPlanList) {
		this.testPlanList = testPlanList;
	}

	public int getTestPlanId() {
		return testPlanId;
	}

	public void setTestPlanId(int testPlanId) {
		this.testPlanId = testPlanId;
	}

	public TestPlan getSingleTestPlan() {
		return singleTestPlan;
	}

	public void setSingleTestPlan(TestPlan singleTestPlan) {
		this.singleTestPlan = singleTestPlan;
	}

	public void setSearchWord(String searchWord) {
		this.searchWord = searchWord;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public String getTestCycle() {
		return testCycle;
	}

	public void setTestCycle(String testCycle) {
		this.testCycle = testCycle;
	}

	public float getPlanedTime() {
		return planedTime;
	}

	public void setPlanedTime(float planedTime) {
		this.planedTime = planedTime;
	}

	public java.util.Date getStartDate() {
		return startDate;
	}

	public void setStartDate(java.util.Date startDate) {
		this.startDate = startDate;
	}

	public java.util.Date getEndDate() {
		return endDate;
	}

	public void setEndDate(java.util.Date endDate) {
		this.endDate = endDate;
	}

	public List<String> getSearchWordTestCase() {
		return searchWordTestCase;
	}

	public void setSearchWordTestCase(List<String> searchWordTestCase) {
		this.searchWordTestCase = searchWordTestCase;
	}

	public String createTestPlan() {
		Date date = new java.sql.Date(System.currentTimeMillis());
		Date creationD  = date;
		Date modificationD  =date;
		FacesContext facesContext = FacesContext.getCurrentInstance(); 
    	String creatorName = facesContext.getExternalContext().getRemoteUser();
		testPlanBean.addTestPlan(this.getSearchWordTestCase(), this.product.getName(), getSummary(), getTestCycle(), getPlanedTime(), this.convertDate( this.getStartDate() ), this.convertDate(this.getEndDate()), modificationD,  creationD,  creatorName);
		// add status message
		Status.addInfo("Plan " + this.summary + " created. ");
		// update plans list
		findAll();
		return PLANS_LIST; 
	}
	
	public String deleteTestPlan() {
		singleTestPlan = (TestPlan) dataTable.getRowData();
		testPlanBean.deleteTestPlan(singleTestPlan);
		// add status message
		Status.addInfo("Plan " + this.summary + " deleted. ");
		// update plans list
		findAll();
		return PLANS_LIST;
	}
	
	
	public String displayTestPlan() {
		TestPlan plan1 = (TestPlan) dataTable.getRowData();
		setSingleTestPlan ( testPlanBean.findTestPlanById(plan1.getId()) );
		this.setStartDate( this.getSingleTestPlan().getStartExecution() );
		this.setEndDate( this.getSingleTestPlan().getEndExecution() );
		this.setProduct( this.getSingleTestPlan().getProduct() );
		return EDIT_PLAN;
	}
	
	public String editTestPlan() {
		Date date = new Date (System.currentTimeMillis());
		FacesContext facesContext = FacesContext.getCurrentInstance(); 
    	String modifierName = facesContext.getExternalContext().getRemoteUser();
		singleTestPlan.setModificationDate( date );
		singleTestPlan.setStartExecution(this.convertDate(getStartDate()));
		singleTestPlan.setEndExecution(this.convertDate(getEndDate()));
		testPlanBean.updateTestPlan(getSingleTestPlan(), modifierName);
		// add status message
		Status.addInfo("Plan " + this.summary + " modified. ");
		// update plans list
		findAll();
		return PLANS_LIST;
	}
	
	//report related 
	public String generateReport(){
		try{
			TestPlan plan1 = (TestPlan) dataTable.getRowData();
			setSingleTestPlan ( testPlanBean.findTestPlanById(plan1.getId()) );
			testPlanBean.generateReport(getSingleTestPlan());
			// add status message
			Status.addInfo("Report created. ");
		}
		catch(IllegalArgumentException il){
			return PLANS_LIST;
		}
		catch(EJBException e){
			Status.addError( e.getCause().getMessage() );
		}
		return PLANS_LIST;
	}
	
	//end report related
	
	//ID, SUMMARY, PRODUCTID, PRODUCTNAME, CREATIOND, MODIFICATIOND, CREATOR, MODIFIER;
	public String  selectSearch(){
		String result;
		switch (this.getSearchDropDown()) {
        case ID:  result = findById( this.getSearchWord()); break;
        case SUMMARY:  result = findBySummary(this.getSearchWord()); break;
        case PRODUCTID:  result = findByProductId(this.getSearchWord()); break;
        case PRODUCTNAME:  result = findByProductName(this.getSearchWord()); break;
        case CREATIOND:  result = findByCreationD(this.getSearchWord()); break;
        case MODIFICATIOND:  result = findByModificationD(this.getSearchWord()); break;
        case ALLTESTPLANS: result = findAll();
        default: result = findAll();
		}
		return result;
	}
	
	////
	public String  findAll(){
		//String result;
		setTestPlanList( ( Collection <TestPlan> ) testPlanBean.findAllTestPlans());
		if ( ! getTestPlanList().isEmpty() ){
			return PLANS_LIST;
		}
		else {
			return PLANS_LIST;
		}
	}
	
	public String  findById(String searchWord){
		setTestPlanId( Integer.parseInt(searchWord));
		try {
			setSingleTestPlan( testPlanBean.findTestPlanById(getTestPlanId()));
			this.setTestPlanList(Arrays.asList(singleTestPlan));
			if (this.getTestPlanList().isEmpty()){
				//message
				Status.addInfo("No plans available with id: " + this.getTestPlanId());
			}
			return PLANS_LIST;
		} catch (NoResultException e) {
			return PLANS_LIST;
		}
		catch(IllegalArgumentException il){
			return PLANS_LIST;
		}
		catch(EJBException e){
			org.tema.web.Status.addError(e.getCause().getMessage());
			return PLANS_LIST;
		}
	}
	
	
	
	@SuppressWarnings("unchecked")
	public String findBySummary( String searchWord){
			try {
				setTestPlanList( ( Collection <TestPlan> ) testPlanBean.findTestPlansBySummary(searchWord));
				if ( getTestPlanList().isEmpty() ){
					Status.addInfo("No plans available with summary: " + searchWord);
					return PLANS_LIST;
				}
				else {
					return PLANS_LIST;
				}
			}
			catch(IllegalArgumentException il){
				return PLANS_LIST;
			}
			catch(EJBException e){
				org.tema.web.Status.addError(e.getCause().getMessage());
				return PLANS_LIST;
			}
	}

	

	public String findByProductId(String searchWord ){
		try{
			setTestPlanId( Integer.parseInt(searchWord));
			this.setTestPlanList( productBean.findProductById( getTestPlanId() ).getPlanSet() );
			if (  getTestPlanList().isEmpty() ){
				Status.addInfo("No plans available with summary: " + searchWord);	
			}
		}
		catch(EJBException e){
			org.tema.web.Status.addError(e.getCause().getMessage());	
		}
		return PLANS_LIST;
	}
	
	@SuppressWarnings("unchecked")
	public String findByProductName(String SearchWord ){
		try{
			this.setTestPlanList( (Collection <TestPlan>) productBean.findProductByName(searchWord).getPlanSet() );
			if (  getTestPlanList().isEmpty() ){
				Status.addInfo("No plans available with product name: " + searchWord);
			}
		}
		catch(EJBException e){
			org.tema.web.Status.addError(e.getCause().getMessage());	
		}
		return PLANS_LIST;
	}
	
	//convert string to date for the creation and modification dates
	public Date convertString (String strDate){
		Date date = null;
		try{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
			date = new Date( sdf.parse(strDate).getTime() );
		}catch(ParseException pe){
			pe.getMessage();
			pe.printStackTrace();
		}
		return date;
	}
	
	
	public String findByCreationD(String cDate){
		try{
			this.setTestPlanList( (Collection <TestPlan>) testPlanBean.findTestPlanByCDate( convertString(cDate) ) );
			if(this.getTestPlanList().isEmpty()){
				Status.addInfo("No plans available with creation date: " + cDate);
			}
		}
		catch(EJBException e){
			org.tema.web.Status.addError(e.getCause().getMessage());	
		}
		return PLANS_LIST;
	}
	
	public String findByModificationD(String cDate){
		try{
			this.setTestPlanList( (Collection <TestPlan>) testPlanBean.findTestPlanByMDate( convertString(cDate) )   );
			if(this.getTestPlanList().isEmpty()){
				Status.addInfo("No plans available with modification date: " + cDate);
			}
		}
		catch(EJBException e){
			org.tema.web.Status.addError(e.getCause().getMessage());	
		}
		return PLANS_LIST;
	}
	

	
    public Collection<SelectItem> getItems() {
    	TestPlanSearchTypes[] values = TestPlanSearchTypes.values();
        Collection<SelectItem> list = new ArrayList<SelectItem>(values.length);
        for (TestPlanSearchTypes value : values) {            
        	list.add(new SelectItem(value, value.getLabel()));                 
        } 
        return list;
    }
    
    public Collection<SelectItem> getProductList(){
    	Collection<Product> products = productBean.findAllProducts();
    	Collection <SelectItem> productList = new ArrayList<SelectItem>( products.size() );  	
    	for( Product prod : products ){
    		productList.add( new SelectItem( prod, prod.getName() ) );
    	}
    	return productList;
    }
    
    public List<SelectItem> getCaseList() {
    	List <SelectItem> caseList;
    	Collection <TestCase> tcList;
//    	if (product != null) {
//    		tcList = product.getTestCaseSet();
//    	} else {
    		tcList = this.testCaseBean.findAllTestCases();
//    	}
    		
		caseList = new ArrayList<SelectItem>( tcList.size() );  	
    	for (TestCase testCase : tcList ) {
    		caseList.add( new SelectItem(testCase.getSummary() ) );
    	}

    	return caseList;
    }
    
    public String refreshCaseList() {
    	return EDIT_PLAN;
    }
    
    public Converter getProductConverter() {
    	return new ProductConverter(productBean);
    }
    
    private java.sql.Date convertDate(java.util.Date date) {
    	return new java.sql.Date(date.getTime());
    }
}
